﻿using DoNetDrive.AspWebSocke.WebSocketClient;
using DoNetDrive.Core.Command;
using DoNetDrive.Core.Connector;
using Face8280WebSocketServer.Command.Models;
using Face8280WebSocketServer.Command.WorkParameter;
using Face8280WebSocketServer.DB.Device;
using Face8280WebSocketServer.DB.Log;
using Face8280WebSocketServer.DTO.FaceDevice;
using Newtonsoft.Json.Serialization;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Face8280WebSocketServer.Command.CommandDetail
{
    public class FaceDriveCommand
    {
        public async Task<FaceDeviceInfo> GetDeviceWorkParameter(AddDeviceParameter parameter)
        {
            try
            {
                var clientDetail = Allocator.GetWebSocketClientDetail(parameter.DeviceSN, parameter.IPAddress, parameter.Port, parameter.Token);
                var deviceInfo = await GetDeviceWorkParameter(clientDetail);
                // deviceInfo.DeviceSn = parameter.DeviceSN;
                deviceInfo.DeviceIP = parameter.IPAddress;
                deviceInfo.DevicePort = parameter.Port;
                deviceInfo.ConnectType = parameter.ConnectType;
                deviceInfo.Token = parameter.Token;
                deviceInfo.DeviceName = parameter.DeviceName;
                return deviceInfo;
            }
            catch
            {
                return null;
            }
        }

        private async Task<FaceDeviceInfo> GetDeviceWorkParameter(INConnectorDetail clientDetail)
        {
            await Allocator.OpenConnectorAsync(clientDetail);
            var detail = Allocator.GetCommandDetail(clientDetail);
            JsonCommand cmd = new GetWorkParameter(detail);
            await Allocator.AddCommandAsync(cmd);
            var workResult = cmd.getResult() as GetWorkParameterResult;
            if (workResult == null)
            {
                return null;
            }
            var result = workResult.ResultObj;
            var deviceInfo = new FaceDeviceInfo
            {
                DeviceSn = result.DeviceSn,
                Door = result.Door ?? 0,
                CompanyName = result.CompanyName,
                Language = result.Language ?? 1,
                MenuPassword = result.MenuPassword,
                SavePhoto = result.SavePhoto ?? 0,
                SaveExternalvisitors = result.SaveExternalvisitors ?? 0,
                Time = result.Time,
                FaceComparison = result.FaceComparison ?? 60,
                FPComparison = 0,
                Distance = result.Distance ?? 2,
                Bioassay = result.Bioassay ?? 0,
                FaceIRThreshold = result.FaceIRThreshold ?? 5,
                Light = result.Light ?? 0,
                FaceMask = result.FaceMask ?? 0,
                MaskThreshold = result.MaskThreshold ?? 50,
                Luminance = result.Luminance ?? 1,
                BodyTmpUse = result.BodyTmp.Use ?? 0,
                BodyTmpFormat = result.BodyTmp.Format ?? 1,
                BodyTmpAlarm = result.BodyTmp.Alarm ?? 37.3,
                WGUse = result.WgOutput?.Use ?? 0,
                WGOrder = result.WgOutput?.Order ?? 1,
                WGType = result.WgOutput?.Type ?? 1,
                CardBytes = result.Cardbytes ?? 3,
                Relay = result.Relay ?? 0,
                ReleaseTime = result.ReleaseTime ?? 3,
                Free = result.Free ?? 0,
                ShortMsg = result.ShortMsg,
                Authentication = result.Authentication ?? 1,
                TimingOpenUse = result.TimingOpen?.Use ?? 0,
                TimingOpen = result.TimingOpen?.Open ?? 3,
                TimingOpenTime = result.TimingOpen?.Time.ToJson(),
                RepeatUse = result.Repeat?.Use ?? 0,
                RepeatMode = result.Repeat?.Mode ?? 2,
                RepeatInterval = result.Repeat?.Interval ?? 5,
                RemindUse = result.Remind?.Use ?? 0,
                RemindDay = result.Remind?.Day ?? 0,
                ElevatorUse = result.Elevator?.Use ?? 0,
                ElevatorRelay = result.Elevator?.Relay.ToJson(),
                FireAlarm = result.FireAlarm ?? 0,
                BlacklistAlarm = result.BlacklistAlarm ?? 0,
                AntiDisassemblyAlarm = result.AntiDisassemblyAlarm ?? 0,
                IllegalVerificationAlarmUse = result.IllegalVerificationAlarm?.Use ?? 0,
                IllegalVerificationAlarmTimes = result.IllegalVerificationAlarm?.Times ?? 0,
                PasswordAlarmUse = result.PasswordAlarm?.Use ?? 0,
                PasswordAlarmMode = result.PasswordAlarm?.Mode ?? 1,
                PasswordAlarmPwd = result.PasswordAlarm?.Pwd,
                OpenTimeoutAlarmUse = result.OpenTimeoutAlarm?.Use ?? 0,
                OpenTimeoutAlarmTimeout = result.OpenTimeoutAlarm?.Timeout ?? 10,
                OpenTimeoutAlarm = result.OpenTimeoutAlarm?.Alarm ?? 1,
                SensorAlarmUse = result.SensorAlarm?.Use ?? 0,
                SensorAlarmTime = result.SensorAlarm?.Time.ToJson(),
                UseCloseAlarm = result.UseCloseAlarm ?? 0,
                Holidays = result.Holidays?.ToJson(),
                TimeGroups = result.TimeGroups?.ToJson(),
                Volume = result.Volume ?? 10,
                Speek = result.Speek ?? 1,
                Grettings = result.Grettings ?? 0,
                StrangerVoice = result.StrangerVoice ?? 0,
                MakerName = result.Maker?.Name,
                MakerUrl = result.Maker?.Url,
                MakerDate = result.Maker?.Date,
                PSPerson = result.Person?.Person,
                PSFace = result.Person?.Face,
                PSCard = result.Person?.Card,
                PSFP = result.Person?.FP,
                PSPasword = result.Person?.Pasword,
                PSAdmin = result.Person?.Admin,
                RSRecord = result.Record?.Record,
                RSSystem = result.Record?.System,
                RSAlarm = result.Record?.Alarm,
                RSDoor = result.Record?.Door,
                //WSRun = result.WorkStatus?.Run ?? 0,
                //WSFormat = result.WorkStatus?.Format ?? 0,
                //WSRestart = result.WorkStatus?.Restart ?? 0,
                //WSUps = result.WorkStatus?.Ups,
                //WSVoltage = result.WorkStatus?.Voltage,
                //WSTemperature = result.WorkStatus?.Temperature,
                //WSRelay = result.WorkStatus?.Relay,
                //WSKeepopen = result.WorkStatus?.Keepopen,
                //WSDoorSensor = result.WorkStatus?.DoorSensor,
                //WSLockSensor = result.WorkStatus?.LockSensor,
                //WSLocked = result.WorkStatus?.Locked,
                //WSMsgPush = result.WorkStatus?.MsgPush,
                //WSAlarm = result.WorkStatus?.Alarm,
                VVer = result.Version?.ver,
                VFace = result.Version?.face,
                VFp = result.Version?.fp,
                //WSServer = result.Server?.Server,
                //WSPort = result.Server?.Port ?? 0,
                //WSToken = result.Server?.Token,
                //WSServerSSLCert = result.Server?.ServerSSLCert,
                //WSStatus = result.Server?.Status ?? 0,
                IKeepalive = result.Ip.Keepalive,
                //WSKeeptime = result.Server?.Keeptime ?? 0,
                //WSReconnectTime = result.Server?.ReconnectTime ?? 0,
                IIp = result.Ip?.Ip,
                IMask = result.Ip?.Mask,
                IMac = result.Ip?.Mac,
                IGateway = result.Ip?.Gateway,
                IDhcp = result.Ip?.Dhcp ?? 0,
                IDns = result.Ip?.Dns,
                IUdp = result.Ip?.Udp ?? 0,
                ITcp = result.Ip?.Tcp ?? 0,
                IWebsocket = result.Ip?.Websocket ?? 0,
                ISsl = result.Ip?.Ssl ?? 0,
                BodyTmpCompensate = result.BodyTmp?.Compensate ?? 0,
                BodyTmpShow = result.BodyTmp?.Show ?? 0,
                TimeZone = result.TimeZone,
                Brightness = result.Brightness ?? 10,
                QRCodePath = result.QRCodePath,
                DoorSensor = result.DoorSensor ?? 0,
                Exposure = result.Exposure ?? 0,
                IR = result.IR ?? 0,
                WiFiGateway = result.WiFi?.Gateway,
                WiFiUse = result.WiFi?.Use ?? 0,
                WiFiIp = result.WiFi?.Ip,
                WiFiMask = result.WiFi?.Mask,
                WiFiName = result.WiFi?.Name,
                WiFiPassword = result.WiFi?.Password,
                WebLoginSwitch = result.WebLoginSwitch,
                LinuxLoginSwitch = result.LinuxLoginSwitch
            };
            return deviceInfo;
        }

        public async Task<FaceDeviceInfo> GetDeviceWorkParameter(string sn)
        {
            var connDetail = await Allocator.GetConnectorDetail(sn);
            if (connDetail == null)
            {

                return null;
            }
            return await GetDeviceWorkParameter(connDetail);
        }

        public async Task<SetWorkParameterResult> SetDeviceWorkParameter(INCommandDetail commandDetail, UpdateDeviceDetailParameter deviceInfo)
        {
            var dto = new SetWorkParam_DTO
            {
                Volume = deviceInfo.Volume,
                Speek = deviceInfo.Speek,
                Grettings = deviceInfo.Grettings,
                StrangerVoice = deviceInfo.StrangerVoice,
                Light = deviceInfo.Light,
                Brightness = deviceInfo.Brightness,
                IR = deviceInfo.IR,
                Language = deviceInfo.Language,
                Maker = new Models.MakerModel
                {
                    Name = deviceInfo.MakerName,
                    Date = deviceInfo.MakerDate,
                    Url = deviceInfo.MakerUrl
                },
                MenuPassword = deviceInfo.MenuPassword ?? "",
                CompanyName = deviceInfo.CompanyName ?? "",
                QRCodePath = deviceInfo.QRCodePath,
                TimeZone = deviceInfo.TimeZone,
                SaveExternalvisitors = deviceInfo.SaveExternalvisitors,
                SavePhoto = deviceInfo.SavePhoto,
                Bioassay = deviceInfo.Bioassay,
                FaceIRThreshold = deviceInfo.FaceIRThreshold,
                Distance = deviceInfo.Distance,
                FaceMask = deviceInfo.FaceMask,
                FaceComparison = deviceInfo.FaceComparison,
                MaskThreshold = deviceInfo.MaskThreshold,
                Luminance = deviceInfo.Luminance,
                Door = deviceInfo.Door,
                WgOutput = new Models.WgOutputModel
                {
                    Use = deviceInfo.WGUse,
                    Order = deviceInfo.WGOrder,
                    Type = deviceInfo.WGType
                },
                Relay = deviceInfo.Relay,
                Free = deviceInfo.Free,
                ReleaseTime = deviceInfo.ReleaseTime,
                ShortMsg = deviceInfo.ShortMsg,
                Authentication = deviceInfo.Authentication,
                TimingOpen = new Models.TimingOpen
                {
                    Use = deviceInfo.TimingOpenUse,
                    Open = deviceInfo.TimingOpen,
                    Time = deviceInfo.TimingOpenTime?.FromJson<WeekModel>()
                },
                Repeat = new RepeatModel
                {
                    Use = deviceInfo.RepeatUse,
                    Mode = deviceInfo.RepeatMode,
                    Interval = deviceInfo.RepeatInterval
                },
                Remind = new Remind
                {
                    Use = deviceInfo.RemindUse,
                    Day = deviceInfo.RemindDay
                },
                Elevator = new Elevator
                {
                    Use = deviceInfo.ElevatorUse,
                    Relay = deviceInfo.ElevatorRelay?.FromJson<ElevatorPort>()
                },
                FireAlarm = deviceInfo.FireAlarm,
                BlacklistAlarm = deviceInfo.BlacklistAlarm,
                AntiDisassemblyAlarm = deviceInfo.AntiDisassemblyAlarm,
                IllegalVerificationAlarm = new IllegalVerificationAlarm
                {
                    Use = deviceInfo.IllegalVerificationAlarmUse,
                    Times = deviceInfo.IllegalVerificationAlarmTimes
                },
                PasswordAlarm = new PasswordAlarm
                {
                    Use = deviceInfo.PasswordAlarmUse,
                    Mode = deviceInfo.PasswordAlarmMode,
                    Pwd = deviceInfo.PasswordAlarmPwd
                },
                OpenTimeoutAlarm = new OpenTimeoutAlarm
                {
                    Use = deviceInfo.OpenTimeoutAlarmUse,
                    Alarm = deviceInfo.OpenTimeoutAlarm,
                    Timeout = deviceInfo.OpenTimeoutAlarmTimeout
                },
                SensorAlarm = new SensorAlarmModel
                {
                    Use = deviceInfo.SensorAlarmUse,
                    Time = deviceInfo.SensorAlarmTime?.FromJson<WeekModel>()
                },
                UseCloseAlarm = deviceInfo.UseCloseAlarm,
                Holidays = deviceInfo.Holidays?.FromJson<List<HolidayDetail>>(),
                TimeGroups = deviceInfo.TimeGroups?.FromJson<List<GroupDetail>>(),
                Time = deviceInfo.Time,
                Cardbytes = deviceInfo.CardBytes,
                Exposure = deviceInfo.Exposure,
                BodyTmp = new BodyTmpModel
                {
                    Use = deviceInfo.BodyTmpUse,
                    Alarm = deviceInfo.BodyTmpAlarm,
                    Compensate = deviceInfo.BodyTmpCompensate,
                    Format = deviceInfo.BodyTmpFormat,
                    Show = deviceInfo.BodyTmpShow
                },
                WebLoginSwitch = deviceInfo.WebLoginSwitch,
                LinuxLoginSwitch = deviceInfo.LinuxLoginSwitch
            };
            if (deviceInfo.OldDeviceSn != null && !deviceInfo.DeviceSn.Equals(deviceInfo.OldDeviceSn))
            {
                dto.NewSN = deviceInfo.DeviceSn;
            }
            if (deviceInfo.OldToken != null && !deviceInfo.Token.Equals(deviceInfo.OldToken))
            {
                dto.NewToken = deviceInfo.Token;
            }
            var cmd = new SetWorkParameter(commandDetail, dto);
            await Allocator.AddCommandAsync(cmd);
            var result = cmd.getResult() as SetWorkParameterResult;
            return result;
        }
    }
}
